home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / os20 / util / newpop40_aga.lha / NewPop-4.0AGA / NewPop.c < prev    next >
C/C++ Source or Header  |  1992-11-07  |  38KB  |  1,420 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /* |_o_o|\\ Copyright (c) 1986 The Software Distillery.  All Rights Reserved */
  3. /* |. o.| || This program may not be distributed without the permission of   */
  4. /* | .  | || the authors.                                                    */
  5. /* | o  | ||    Dave Baker     Ed Burnette  Stan Chow    Jay Denebeim        */
  6. /* |  . |//     Gordon Keener  Jack Rouse   John Toebes  Doug Walker         */
  7. /* ======          BBS:(919)-471-6436      VOICE:(919)-469-4210              */
  8. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  9.  
  10. /*
  11.  * VERY loosely based on the input.device example by Rob Peck, 12/1/85
  12.  *
  13.  *
  14.  * Additions and modifications Copyright (c) 1989, 1990, 1991 Loren J. Rittle
  15.  * Modifications Copyright (c) 1990 Ed A. Hutchins and Loren J. Rittle
  16.  *
  17.  * As stated in the original POPCLI documentation file:
  18.  *
  19.  * Permission is hereby granted to distribute this program provided
  20.  * both the documentation accompanies the executable and that no
  21.  * charge is made for its distribution.
  22.  * I assume that this statement includes the right to modify the source
  23.  * and futher distribute the modified work under this same agreement. - LJR
  24.  * (Actually, at this point, 'diff newpop.c popcli3.c | wc'
  25.  * > 'wc -c newpop.c' + 'wc -c popcli3.c'. :-)
  26.  *
  27.  *
  28.  *    Note:    Some code to do the Q*X pattern lifted (and modified) from:
  29.  *         Line drawing demo for the Commodore/Amiga
  30.  *         Written by John Riley, Lattice, Inc.
  31.  *
  32.  *    Note:   The spawning of a lower priority task to do graphics
  33.  *        was inspired by Mackie to some degree (and by
  34.  *        one person who claimed that NewPop slowed down
  35.  *        HST modem transfers! I think that they were
  36.  *        on a non-A3000 class machine :-)  Later, I got
  37.  *        a report that it also happened on an A3000! :-(
  38.  *        See NICENEWPOP in `[s:].newpoprc'.
  39.  *
  40.  *    UpfrontLayer is used instead of WindowToFront() because of
  41.  *    a WorkBench/INTUITION bug. From dmouse.doc:
  42.  *
  43.  *    WORKBENCH USERS!!!!!!!!!! There appears to be a bug in
  44.  *    intuition's WindowToFront() call, which can lock up
  45.  *     intuition when workbench icons are active.  Under the
  46.  *    defaults, this will occur whenever you depress the left
  47.  *     mouse button over an icon.
  48.  *
  49.  *     Thanks to Matt Dillon for showing the work around
  50.  *     in DMouse's source code.
  51.  *
  52.  *    See ChangeLog for the record of changes.
  53.  *
  54.  *    Loren J. Rittle
  55.  *    l-rittle@uiuc.edu
  56.  */
  57.  
  58.  
  59. /* * * * * * * * * * * INCLUDES * * * * * * * * * * * * */
  60. #pragma msg 148 ignore push
  61. #pragma msg 149 ignore push
  62. #pragma msg 61 ignore push
  63. #include <exec/exec.h>
  64. #include <dos/dos.h>
  65. #include <dos/dostags.h>
  66. #include <devices/timer.h>
  67. #include <devices/input.h>
  68. #include <devices/inputevent.h>
  69. #include <intuition/intuitionbase.h>
  70. #include <graphics/gfxmacros.h>
  71. #include <graphics/layers.h>
  72. #include <graphics/gfxbase.h>
  73. #include <graphics/text.h>
  74. /*int GetString (char *, char *, struct Window *, int, int);
  75. #include <proto/req.h>*/
  76. #include <proto/dos.h>
  77. #include <proto/exec.h>
  78. #include <proto/layers.h>
  79. #include <proto/intuition.h>
  80. #include <proto/graphics.h>
  81. #include <proto/diskfont.h>
  82. #pragma msg 149 pop
  83. #pragma msg 61 pop
  84.  
  85. #include <string.h>
  86. #include <time.h>
  87. #include <math.h>
  88. #include <stdio.h>
  89. #include <stdlib.h>
  90.  
  91. LoadRGB32 (void *, unsigned long *table);
  92. #pragma libcall GfxBase LoadRGB32 372 9802
  93.  
  94. /* * * * * * * * * * * CONSTANTS * * * * * * * * * * * * */
  95. #define PORTNAME     "NewPop.port"
  96.  /* The name of our well known *PRIVATE* message port */
  97.  
  98. #define MAXCMD        200
  99. #define MAXTASKNAME    32
  100. #define MAXFONTNAME    32
  101. #define MAXPASSWORD    32
  102.  /* Maximum string size of various things */
  103.  
  104. #define BANNER \
  105. "\x9B" "0;33mNewPop\x9B" \
  106. "0m v4.0 by Loren J. Rittle - Copyright \xA9 1989 - 1991 Based upon:\n" \
  107. "\x9B" "0;33mPOPCLI III\x9B" \
  108. "0m by John Toebes - Copyright \xA9 1987 The Software Distillery\n"
  109.  /* The hello banner */
  110.  
  111. #define ALREADYHEREMESSAGE \
  112. "NewPop is already running, you should use `break [cli number of NewPop]'\n" \
  113. "to kill it before starting another.  Or, if started via the WorkBench,\n" \
  114. "another double click on the NewPop icon will stop it.\n"
  115.  /* The already here message :-) */
  116.  
  117.  
  118. /* * * * * * * * * * * * * * * * TYPES * * * * * * * * * * * * * */
  119. struct color
  120. {
  121.   int red, green, blue;
  122. };
  123.  
  124. enum OptionTypes
  125. {
  126.   boolean, integer, string
  127. };
  128.  
  129. struct NewPopOption
  130. {
  131.   char *name;
  132.   enum OptionTypes type;
  133.   union
  134.   {
  135.     int ivalue;
  136.     char *svalue;
  137.   } value;
  138.   int min, max;
  139. };
  140.  
  141.  
  142. /* * * * * * * * * * * EXTERNALS AND GLOBAL DATA * * * * * * * * */
  143. char FontName[MAXFONTNAME] = "Helvetica.font";
  144. char TaskName[MAXTASKNAME] = "gvpscsi.device";
  145. #ifndef LJR_FAVORITE
  146. char Cmd[MAXCMD] = "NEWCLI >NIL:";
  147. #else
  148. char Cmd[MAXCMD] = "NewWSH <nil: >nil: cnn:0/11/640/189/WShell/c";
  149. #endif
  150. char PassWord[MAXPASSWORD] = "Amiga";
  151.  
  152. /*
  153.  *  See .newpoprc for the meanings of these options!
  154.  */
  155. struct NewPopOption NewPopOptions[] =
  156. {
  157. #define NICENEWPOP (NewPopOptions[0].value.ivalue)
  158.   {"NICENEWPOP", boolean, 1, 0, 1},
  159. #define NEWPOPLITE (NewPopOptions[1].value.ivalue)
  160.   {"NEWPOPLITE", boolean, 0, 0, 1},
  161. #define WEWANTWINDOWDRAG (NewPopOptions[2].value.ivalue)
  162.   {"WEWANTWINDOWDRAG", boolean, 0, 0, 1},
  163. #define SCSITASKNAME (NewPopOptions[3].value.svalue)
  164.   {"SCSITASKNAME", string, (int) TaskName, 0, MAXTASKNAME},
  165. #define FONTNAME (NewPopOptions[4].value.svalue)
  166.   {"FONTNAME", string, (int) FontName, 0, MAXFONTNAME},
  167. #define COMMAND (NewPopOptions[5].value.svalue)
  168.   {"COMMAND", string, (int) Cmd, 0, MAXCMD},
  169. #define MAXSCSIUSAGE (NewPopOptions[6].value.ivalue)
  170.   {"MAXSCSIUSAGE", integer, 55, 20, 255},
  171. #define SCSIIOMONWIDTH (NewPopOptions[7].value.ivalue)
  172.   {"SCSIIOMONWIDTH", integer, 100, 0, 1024},
  173. #define CPULOADMONWIDTH (NewPopOptions[8].value.ivalue)
  174.   {"CPULOADMONWIDTH", integer, 100, 0, 1024},
  175. #define GAPBETWEEN2 (NewPopOptions[9].value.ivalue)
  176.   {"GAPBETWEEN2", integer, 16, 0, 256},
  177. #define GAPBETWEEN (NewPopOptions[10].value.ivalue)
  178.   {"GAPBETWEEN", integer, 16, 0, 256},
  179. #define FONTSIZE (NewPopOptions[11].value.ivalue)
  180.   {"FONTSIZE", integer, 9, 4, 56},
  181. #define STARTYOFFSET (NewPopOptions[12].value.ivalue)
  182.   {"STARTYOFFSET", integer, 7, 2, 60},
  183. #define MAXTEXTWIDTH (NewPopOptions[13].value.ivalue)
  184.   {"MAXTEXTWIDTH", integer, 107, 10, 1024},
  185. #define STARTXOFFSET (NewPopOptions[14].value.ivalue)
  186.   {"STARTXOFFSET", integer, 56, 10, 200},
  187. #define WINDOWHEIGHT (NewPopOptions[15].value.ivalue)
  188.   {"WINDOWHEIGHT", integer, 8, 4, 56},
  189. #define TIMEOUT (NewPopOptions[16].value.ivalue)
  190.   {"TIMEOUT", integer, 180, 0, 0x00ffffff},
  191. #define POPKEY (NewPopOptions[17].value.ivalue)
  192.   {"POPKEY", integer, 69, 0, 255},
  193. #define BLANKERPRIORITY (NewPopOptions[18].value.ivalue)
  194.   {"BLANKERPRIORITY", integer, -20, -20, 10},
  195. #define ULC (NewPopOptions[19].value.ivalue)
  196.   {"ULC", integer, 0, 0, 2},
  197. #define URC (NewPopOptions[20].value.ivalue)
  198.   {"URC", integer, 1, 0, 2},
  199. #define LLC (NewPopOptions[21].value.ivalue)
  200.   {"LLC", integer, 0, 0, 2},
  201. #define LRC (NewPopOptions[22].value.ivalue)
  202.   {"LRC", integer, 2, 0, 2},
  203. #define INSTANTKEY (NewPopOptions[23].value.ivalue)
  204.   {"INSTANTKEY", integer, 0, 0, 255},
  205. #define DEFEATKEY (NewPopOptions[24].value.ivalue)
  206.   {"DEFEATKEY", integer, 0, 0, 255},
  207. #define LOCK (NewPopOptions[25].value.ivalue)
  208.   {"LOCK", boolean, 0, 0, 1},
  209. #define PASSWORD (NewPopOptions[26].value.svalue)
  210.   {"PASSWORD", string, (int) PassWord, 0, MAXPASSWORD},
  211. #define MEMORYMONWIDTH (NewPopOptions[27].value.ivalue)
  212.   {"MEMORYMONWIDTH", integer, 0, 0, 1024},
  213. #define GAPBETWEEN3 (NewPopOptions[28].value.ivalue)
  214.   {"GAPBETWEEN3", integer, 0, 0, 256},
  215. #define BACKDROPWINDOW (NewPopOptions[29].value.ivalue)
  216.   {"BACKDROPWINDOW", boolean, 1, 0, 1},
  217. #define WIMPYCLOCK (NewPopOptions[30].value.ivalue)
  218.   {"WIMPYCLOCK", boolean, 0, 0, 1},
  219. /* Add new enties before this line! */
  220.   {NULL, boolean, 0, 0, 0}
  221. };
  222.  
  223. struct IntuitionBase *IntuitionBase;
  224. struct LayersBase *LayersBase;
  225. struct GfxBase *GfxBase;
  226. struct Library *DiskfontBase;
  227. struct DosLibrary *DosBase;
  228. struct ExecBase *ExecBase;
  229. struct Library *ReqBase;
  230.  
  231. struct NewScreen NewScreen =
  232. {0, 0, 640, 400, 1, 0, 1, HIRES | LACE, SCREENBEHIND | SCREENQUIET | CUSTOMSCREEN, NULL, NULL, NULL, NULL};
  233.  
  234. struct NewWindow NewBlankerWindow =
  235. {0, 0, 640, 400, 0xff, 0xff, 0, RMBTRAP | BORDERLESS | BACKDROP | SIMPLE_REFRESH | ACTIVATE, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN};
  236.  
  237. int WindowWidth, WindowHeight;
  238.  
  239. struct Gadget WDragGadget =
  240. {NULL, 0, 0, 0, 0, GADGHNONE, NULL, WDRAGGING, NULL, NULL, NULL, NULL, NULL, 0, 0};
  241.  
  242. struct NewWindow NewWindow =
  243. {0, 0, 0, 0, 2, 1, 0, BORDERLESS | NOCAREREFRESH, &WDragGadget, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN};
  244.  
  245. struct Task *buddy;
  246. ULONG creatclisig;
  247. ULONG unblanksig;
  248. ULONG mousemovesig;
  249. ULONG noevents;
  250. short creatsignum = -1;
  251. short blanksignum = -1;
  252. short mousemovenum = -1;
  253. struct Screen *blankscreen;
  254. struct Window *blankwindow;
  255. USHORT instantblank, defeatblank;
  256. ULONG scsiDisp;
  257. struct Task *child;
  258. struct Task *securer;
  259. struct ViewPort *blankVP;
  260. struct RastPort *blankRP;
  261. USHORT xlim, ylim;
  262. int maxchip, maxfast;
  263. USHORT StartedFromWB;
  264.  
  265. /* * * * * * * * * * * PROTOTYPES * * * * * * * * * * * * */
  266. struct InputEvent *__saveds __asm myhandler (register __a0 struct InputEvent *);
  267. void createchild (void);
  268. void __saveds blankertask (void);
  269. void killchild (void);
  270. void createsecurer (void);
  271. void __saveds securertask (void);
  272. void killsecurer (void);
  273. void __saveds scsifriendlosing (void);
  274. int ParseConfigFile (void);
  275. int __stdargs main (int argc, char *argv[]);
  276. void changecolor (void);
  277. void updatedisplay (void);
  278. void QueueTimer (struct timerequest *, ULONG);
  279.  
  280.  
  281. /* * * * * * * * * * * OUR ROUTINES * * * * * * * * * * * */
  282. struct InputEvent *__saveds __asm 
  283. myhandler (register __a0 struct InputEvent * ev)
  284. {
  285.   struct InputEvent *ep, *laste;
  286.  
  287.   for (ep = ev, laste = NULL; ep != NULL; ep = ep->ie_NextEvent)
  288.     {
  289.       if ((ep->ie_Class == IECLASS_RAWKEY) &&
  290.       (ep->ie_Qualifier & IEQUALIFIER_LCOMMAND))
  291.     {
  292.       if ((ep->ie_Code == POPKEY) && (POPKEY))
  293.         Signal (buddy, creatclisig);
  294.       else if ((ep->ie_Code == DEFEATKEY) && (DEFEATKEY))
  295.         {
  296.           defeatblank = !defeatblank;
  297.           instantblank = 0;
  298.         }
  299.       else if ((ep->ie_Code == INSTANTKEY) && (INSTANTKEY))
  300.         {
  301.           defeatblank = 0;
  302.           instantblank = !instantblank;
  303.         }
  304.       else
  305.         goto nomatch;
  306.       if (laste == NULL)
  307.         ev = ep->ie_NextEvent;
  308.       else
  309.         laste->ie_NextEvent = ep->ie_NextEvent;
  310.     }
  311.       else
  312. nomatch:
  313.     laste = ep;
  314.  
  315.       if (ep->ie_Class == IECLASS_RAWMOUSE)
  316.     Signal (buddy, mousemovesig);
  317.  
  318.       if (ep->ie_Class != IECLASS_TIMER)
  319.     {
  320.       noevents = 0;
  321.       if (blankscreen)
  322.         Signal (buddy, unblanksig);
  323.     }
  324.     }
  325.   return (ev);
  326. }
  327.  
  328. void 
  329. createchild (void)
  330. {
  331.   child = CreateTask ("NewPopBlanker", BLANKERPRIORITY, (APTR) blankertask, 4000L);
  332. }
  333.  
  334. void __saveds 
  335. blankertask (void)
  336. {
  337.   struct MsgPort *timerport2;
  338.   struct timerequest *timerreq2 = NULL;
  339.  
  340.   if (timerport2 = CreatePort ("NewPopTimerPort2", 0))
  341.     if (timerreq2 = (struct timerequest *) CreateExtIO (timerport2, sizeof (struct timerequest)))
  342.       if (!(OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) timerreq2, 0)))
  343.     {
  344.       while (!(SetSignal (0L, 0L) & SIGBREAKF_CTRL_C))
  345.         {
  346.           changecolor ();
  347.           updatedisplay ();
  348.           if (child->tc_Node.ln_Pri == 10)
  349.         SetTaskPri (child, BLANKERPRIORITY);
  350.           timerreq2->tr_node.io_Command = TR_ADDREQUEST;
  351.           timerreq2->tr_time.tv_secs = 0;
  352.           timerreq2->tr_time.tv_micro = 1000000 / 60;
  353.           DoIO ((struct IORequest *) timerreq2);
  354.         }
  355.     }
  356.       else
  357.     Wait (SIGBREAKF_CTRL_C);
  358.   if (timerreq2)
  359.     {
  360.       if (timerreq2->tr_node.io_Device)
  361.     CloseDevice ((struct IORequest *) timerreq2);
  362.       DeleteExtIO ((struct IOStdReq *) timerreq2);
  363.     }
  364.   if (timerport2)
  365.     DeletePort (timerport2);
  366.   Signal (buddy, SIGBREAKF_CTRL_D);
  367.   Wait (0L);
  368. }
  369.  
  370. void 
  371. killchild (void)
  372. {
  373.   Signal (child, SIGBREAKF_CTRL_C);
  374.   SetTaskPri (child, 20L);
  375.   Wait (SIGBREAKF_CTRL_D);
  376.   DeleteTask (child);
  377.   child = NULL;
  378. }
  379.  
  380. void 
  381. createsecurer (void)
  382. {
  383.   securer = CreateTask ("NewPopSecurer", 19, (APTR) securertask, 4000L);
  384. }
  385.  
  386. void __saveds 
  387. securertask (void)
  388. {
  389.   while (!(SetSignal (0L, 0L) & SIGBREAKF_CTRL_C))
  390.     {
  391.       ScreenToFront (blankscreen);
  392.       changecolor ();
  393.     }
  394.   Signal (buddy, SIGBREAKF_CTRL_D);
  395.   Wait (0L);
  396. }
  397.  
  398. void 
  399. killsecurer (void)
  400. {
  401.   Signal (securer, SIGBREAKF_CTRL_C);
  402.   Wait (SIGBREAKF_CTRL_D);
  403.   DeleteTask (securer);
  404.   securer = NULL;
  405. }
  406.  
  407. void __saveds 
  408. scsifriendlosing (void)
  409. {
  410.   scsiDisp++;
  411. }
  412.  
  413. int 
  414. ParseConfigFile (void)
  415. {
  416.   BPTR configFile;
  417. #define INPUTBUFFERSIZE 512
  418.   char buffer[INPUTBUFFERSIZE];
  419.   int bp;
  420.   int keyword;
  421. #define KEYWORDBUFFERSIZE 31
  422.   char keywordbuffer[KEYWORDBUFFERSIZE + 1];
  423.   int keywordbp;
  424.   int charinbuffer;
  425.   int state = 0;
  426.   int line = 1;
  427.   int i;
  428.   int neg;
  429.  
  430.   configFile = Open (".newpoprc", MODE_OLDFILE);
  431.   if (!configFile)
  432.     configFile = Open ("s:.newpoprc", MODE_OLDFILE);
  433.   if (!configFile)
  434.     return 0;
  435.  
  436.   while (charinbuffer = Read (configFile, buffer, INPUTBUFFERSIZE))
  437.     {
  438.       for (bp = 0; bp != charinbuffer; bp++)
  439.     {
  440.       switch (state)
  441.         {
  442.         case 0:
  443.           if (buffer[bp] == '#')
  444.         state = 1;
  445.           else if (buffer[bp] == '\n')
  446.         line++;
  447.           else if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
  448.         {
  449.           keywordbuffer[0] = buffer[bp] - 32;
  450.           keywordbp = 1;
  451.           state = 2;
  452.         }
  453.           else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
  454.         {
  455.           keywordbuffer[0] = buffer[bp];
  456.           keywordbp = 1;
  457.           state = 2;
  458.         }
  459.           else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
  460.         {
  461.           state = 1;
  462.           goto out;
  463.         }
  464.           break;
  465.         case 1:
  466.           if (buffer[bp] == '\n')
  467.         {
  468.           line++;
  469.           state = 0;
  470.         }
  471.           break;
  472.         case 2:
  473.           if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
  474.         {
  475.           if (keywordbp >= KEYWORDBUFFERSIZE)
  476.             {
  477.               state = 1;
  478.               goto out;
  479.             }
  480.           keywordbuffer[keywordbp++] = buffer[bp] - 32;
  481.         }
  482.           else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
  483.         {
  484.           if (keywordbp >= KEYWORDBUFFERSIZE)
  485.             {
  486.               state = 1;
  487.               goto out;
  488.             }
  489.           keywordbuffer[keywordbp++] = buffer[bp];
  490.         }
  491.           else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
  492.         {
  493.           if (keywordbp >= KEYWORDBUFFERSIZE)
  494.             {
  495.               state = 1;
  496.               goto out;
  497.             }
  498.           keywordbuffer[keywordbp++] = buffer[bp];
  499.         }
  500.           else if ((buffer[bp] == ' ') || (buffer[bp] == '\t'))
  501.         {
  502.           keywordbuffer[keywordbp] = '\0';
  503.           for (i = 0; NewPopOptions[i].name; i++)
  504.             if (!strcmp (NewPopOptions[i].name, keywordbuffer))
  505.               break;
  506.           if (!NewPopOptions[i].name)
  507.             {
  508.               state = 1;
  509.               goto out;
  510.             }
  511.           keyword = i;
  512.           state = 3;
  513.         }
  514.           else
  515.         {
  516.           state = 1;
  517.           goto out;
  518.         }
  519.           break;
  520.         case 3:
  521.           if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
  522.         switch (NewPopOptions[keyword].type)
  523.           {
  524.           case boolean:
  525.             state = 4;
  526.             if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
  527.               {
  528.             keywordbuffer[0] = buffer[bp] - 32;
  529.             keywordbp = 1;
  530.               }
  531.             else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
  532.               {
  533.             keywordbuffer[0] = buffer[bp];
  534.             keywordbp = 1;
  535.               }
  536.             else
  537.               {
  538.             state = 1;
  539.             goto out;
  540.               }
  541.             break;
  542.           case integer:
  543.             state = 5;
  544.             neg = 0;
  545.             if (buffer[bp] == '-')
  546.               {
  547.             neg = 1;
  548.             NewPopOptions[keyword].value.ivalue = 0;
  549.               }
  550.             else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
  551.               NewPopOptions[keyword].value.ivalue = buffer[bp] - '0';
  552.             else
  553.               {
  554.             state = 1;
  555.             goto out;
  556.               }
  557.             break;
  558.           case string:
  559.             state = 6;
  560.             if (buffer[bp] != '"')
  561.               {
  562.             state = 1;
  563.             goto out;
  564.               }
  565.             i = 0;
  566.             break;
  567.           }
  568.           break;
  569.         case 4:
  570.           if ((buffer[bp] <= 'z') && (buffer[bp] >= 'a'))
  571.         {
  572.           if (keywordbp >= KEYWORDBUFFERSIZE)
  573.             {
  574.               state = 1;
  575.               goto out;
  576.             }
  577.           keywordbuffer[keywordbp++] = buffer[bp] - 32;
  578.         }
  579.           else if ((buffer[bp] <= 'Z') && (buffer[bp] >= 'A'))
  580.         {
  581.           if (keywordbp >= KEYWORDBUFFERSIZE)
  582.             {
  583.               state = 1;
  584.               goto out;
  585.             }
  586.           keywordbuffer[keywordbp++] = buffer[bp];
  587.         }
  588.           else if ((buffer[bp] == ' ') || (buffer[bp] == '\t') || (buffer[bp] == '\n'))
  589.         {
  590.           keywordbuffer[keywordbp] = '\0';
  591.           NewPopOptions[i].value.ivalue = 2;
  592.           if (!strcmp ("TRUE", keywordbuffer))
  593.             NewPopOptions[i].value.ivalue = 1;
  594.           if (!strcmp ("FALSE", keywordbuffer))
  595.             NewPopOptions[i].value.ivalue = 0;
  596.           if (!strcmp ("ON", keywordbuffer))
  597.             NewPopOptions[i].value.ivalue = 1;
  598.           if (!strcmp ("OFF", keywordbuffer))
  599.             NewPopOptions[i].value.ivalue = 0;
  600.           if (NewPopOptions[i].value.ivalue == 2)
  601.             {
  602.               state = 1;
  603.               goto out;
  604.             }
  605.           if (buffer[bp] == '\n')
  606.             {
  607.               line++;
  608.               state = 0;
  609.             }
  610.           else
  611.             state = 7;
  612.         }
  613.           else
  614.         {
  615.           state = 1;
  616.           goto out;
  617.         }
  618.           break;
  619.         case 5:
  620.           if (buffer[bp] == '\n')
  621.         {
  622.           if (neg)
  623.             NewPopOptions[keyword].value.ivalue *= -1;
  624.           if (NewPopOptions[keyword].value.ivalue > NewPopOptions[keyword].max)
  625.             {
  626.               state = 1;
  627.               goto out;
  628.             }
  629.           if (NewPopOptions[keyword].value.ivalue < NewPopOptions[keyword].min)
  630.             {
  631.               state = 1;
  632.               goto out;
  633.             }
  634.           line++;
  635.           state = 0;
  636.         }
  637.           else if ((buffer[bp] == ' ') || (buffer[bp] == '\t'))
  638.         {
  639.           if (neg)
  640.             NewPopOptions[keyword].value.ivalue *= -1;
  641.           if (NewPopOptions[keyword].value.ivalue > NewPopOptions[keyword].max)
  642.             {
  643.               state = 1;
  644.               goto out;
  645.             }
  646.           if (NewPopOptions[keyword].value.ivalue < NewPopOptions[keyword].min)
  647.             {
  648.               state = 1;
  649.               goto out;
  650.             }
  651.           state = 7;
  652.         }
  653.           else if ((buffer[bp] <= '9') && (buffer[bp] >= '0'))
  654.         {
  655.           NewPopOptions[keyword].value.ivalue *= 10;
  656.           NewPopOptions[keyword].value.ivalue += buffer[bp] - '0';
  657.         }
  658.           else
  659.         {
  660.           state = 1;
  661.           goto out;
  662.         }
  663.           break;
  664.         case 6:
  665.           if ((buffer[bp] == '\n') || (i >= NewPopOptions[keyword].max))
  666.         {
  667.           state = 1;
  668.           goto out;
  669.         }
  670.           NewPopOptions[keyword].value.svalue[i++] = buffer[bp];
  671.           if (buffer[bp] == '"')
  672.         {
  673.           NewPopOptions[keyword].value.svalue[--i] = '\0';
  674.           state = 8;
  675.         }
  676.           break;
  677.         case 7:
  678.           if (buffer[bp] == '#')
  679.         state = 1;
  680.           else if (buffer[bp] == '\n')
  681.         {
  682.           line++;
  683.           state = 0;
  684.         }
  685.           else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
  686.         {
  687.           state = 1;
  688.           goto out;
  689.         }
  690.           break;
  691.         case 8:
  692.           if (buffer[bp] == '\n')
  693.         {
  694.           line++;
  695.           state = 0;
  696.         }
  697.           else if ((buffer[bp] != ' ') && (buffer[bp] != '\t'))
  698.         {
  699.           state = 1;
  700.           goto out;
  701.         }
  702.           else
  703.         state = 7;
  704.           break;
  705.         default:
  706.           state = 1;
  707.           goto out;
  708.         }
  709.     }
  710.     }
  711. out:
  712.  
  713.   Close (configFile);
  714.   if (state)
  715.     {
  716.       if (!StartedFromWB)
  717.     {
  718.           sprintf (buffer, "NewPop: parse error on line %d of .newpoprc\n", line);
  719.       Write (Output (), buffer, strlen (buffer));
  720.     }
  721.       return 1;
  722.     }
  723.   return 0;
  724. }
  725.  
  726. int __stdargs 
  727. main (int argc, char *argv[])
  728. {
  729.   USHORT scsifriendinstalled = 0;
  730.   ULONG timersig, LIdle, LDisp;
  731.   BPTR nullfh = NULL;
  732.   struct MsgPort *port;
  733.   struct MsgPort *timerport = NULL;
  734.   struct MsgPort *inputDevPort = NULL;
  735.   struct timerequest *timerreq = NULL;
  736.   struct IOStdReq *inputRequestBlock = NULL;
  737.   struct TextFont *textFont = NULL;
  738.   struct Task *scsifriend;
  739.   struct Interrupt handlerStuff;
  740.   struct Window *titlewindow = NULL;
  741.   struct RastPort *titleRP;
  742.   UBYTE oldPriority;
  743.  
  744.   {
  745.     buddy = FindTask (NULL);
  746.     oldPriority = SetTaskPri (buddy, 20);
  747.     if (!argc)
  748.       StartedFromWB = 1;
  749.     Forbid ();
  750.     if (!(port = FindPort (PORTNAME)))
  751.       {
  752.     if (!(port = CreatePort (PORTNAME, 0)))
  753.       {
  754.         Permit ();
  755.         goto grandexit;
  756.       }
  757.     Permit ();
  758.     if (!StartedFromWB)
  759.       Write (Output (), BANNER, sizeof (BANNER));
  760.     if (ParseConfigFile ())
  761.       goto abort;
  762.       }
  763.     else
  764.       {
  765.     Permit ();
  766.     if (StartedFromWB)
  767.       Signal (port->mp_SigTask, SIGBREAKF_CTRL_C);
  768.     else
  769.       Write (Output (), ALREADYHEREMESSAGE, sizeof (ALREADYHEREMESSAGE));
  770.     goto grandexit;
  771.       }
  772.     if (!(nullfh = Open ("NIL:", MODE_NEWFILE)))
  773.       goto abort;
  774.     if (!(inputDevPort = CreatePort ("NewPopInputPort", 0)))
  775.       goto abort;
  776.     if (!(inputRequestBlock = (void *) CreateExtIO (inputDevPort, sizeof (struct IOStdReq))))
  777.       goto abort;
  778.     if (!(timerport = CreatePort ("NewPopTimerPort", 0)))
  779.       goto abort;
  780.     if (!(timerreq = (struct timerequest *) CreateExtIO (timerport, sizeof (struct timerequest))))
  781.       goto abort;
  782.     if ((creatsignum = AllocSignal (-1)) == -1)
  783.       goto abort;
  784.     if ((blanksignum = AllocSignal (-1)) == -1)
  785.       goto abort;
  786.     if ((mousemovenum = AllocSignal (-1)) == -1)
  787.       goto abort;
  788.     if (!(GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0)))
  789.       goto abort;
  790.     if (!(LayersBase = (struct LayersBase *) OpenLibrary ("layers.library", 0)))
  791.       goto abort;
  792.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library", 0)))
  793.       goto abort;
  794.     if (!(DiskfontBase = OpenLibrary ("diskfont.library", 0)))
  795.       goto abort;
  796.     if (!(ExecBase = (struct ExecBase *) OpenLibrary ("exec.library", 0)))
  797.       goto abort;
  798.     if (LOCK)
  799.       ReqBase = OpenLibrary ("req.library", 0);
  800.     if (!NEWPOPLITE)
  801.       {
  802.     if (MEMORYMONWIDTH)
  803.       {
  804.         struct MemHeader *mem;
  805.  
  806.         Forbid ();
  807.         for (mem = (struct MemHeader *)ExecBase->MemList.lh_Head;
  808.          mem->mh_Node.ln_Succ;
  809.          mem = (struct MemHeader *)mem->mh_Node.ln_Succ)
  810.           {
  811.         if (mem -> mh_Attributes & MEMF_CHIP)
  812.           maxchip += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
  813.         /* Just in case we have something that is both chip and fast... */
  814.         if (mem -> mh_Attributes & MEMF_FAST)
  815.           maxfast += ((ULONG) mem -> mh_Upper - (ULONG) mem -> mh_Lower);
  816.           }
  817.         Permit ();
  818.       }
  819.     else
  820.       GAPBETWEEN3 = 0;
  821.     if (SCSIIOMONWIDTH)
  822.       {
  823.         Forbid ();
  824.         if (scsifriend = FindTask (SCSITASKNAME))
  825.           if (!(scsifriend->tc_Flags & TF_SWITCH))
  826.             {
  827.               scsifriend->tc_Switch = scsifriendlosing;
  828.               scsifriend->tc_Flags |= TF_SWITCH;
  829.               scsifriendinstalled = 1;
  830.             }
  831.         Permit ();
  832.       }
  833.     else
  834.       GAPBETWEEN2 = 0;
  835.     if (!CPULOADMONWIDTH)
  836.       GAPBETWEEN = 0;
  837.     WindowWidth = MEMORYMONWIDTH + GAPBETWEEN3 + SCSIIOMONWIDTH +
  838.       GAPBETWEEN2 + CPULOADMONWIDTH + GAPBETWEEN + MAXTEXTWIDTH;
  839.     WindowHeight = WINDOWHEIGHT;
  840.     NewWindow.LeftEdge = GfxBase->NormalDisplayColumns - WindowWidth - STARTXOFFSET;
  841.     NewWindow.TopEdge = 1;
  842.     NewWindow.Width = WindowWidth;
  843.     NewWindow.Height = WindowHeight;
  844.     if (WEWANTWINDOWDRAG)
  845.       {
  846.         WDragGadget.Height = WindowHeight;
  847.         WDragGadget.Width = WindowWidth;
  848.       }
  849.     else
  850.       NewWindow.FirstGadget = NULL;
  851.     if (BACKDROPWINDOW)
  852.       NewWindow.Flags |= BACKDROP;
  853.     if ((NewWindow.LeftEdge < 0) || !(titlewindow = OpenWindow (&NewWindow)))
  854.       goto abort;
  855.     titleRP = titlewindow->RPort;
  856.     SetAPen (titleRP, 1);
  857.     SetBPen (titleRP, 1);
  858.     SetDrMd (titleRP, JAM2);
  859.     RectFill (titleRP, 0, 0, (WindowWidth - 1), (WindowHeight - 1));
  860.     if (MAXTEXTWIDTH)
  861.       {
  862.         struct TextAttr textAttr = {NULL, 0, 0, 0};
  863.  
  864.         textAttr.ta_Name = FONTNAME;
  865.         textAttr.ta_YSize = FONTSIZE;
  866.         if (textFont = OpenFont (&textAttr))
  867.           {
  868.             if ((textFont->tf_YSize != FONTSIZE) || (textFont->tf_Style != 0))
  869.               {
  870.             CloseFont (textFont);
  871.             if (!(textFont = OpenDiskFont (&textAttr)))
  872.               goto abort;
  873.               }
  874.           }
  875.         else
  876.           {
  877.             if (!(textFont = OpenDiskFont (&textAttr)))
  878.               goto abort;
  879.           }
  880.         SetFont (titleRP, textFont);
  881.       }
  882.     LIdle = ExecBase->IdleCount;
  883.     LDisp = ExecBase->DispCount;
  884.       }
  885.     if (OpenDevice ("input.device", 0, (struct IORequest *) inputRequestBlock, 0))
  886.       goto abort;
  887.     handlerStuff.is_Data = (APTR) NULL;
  888.     handlerStuff.is_Code = (VOID (*) ()) myhandler;
  889.     handlerStuff.is_Node.ln_Pri = 51;
  890.     timersig = (1 << timerport->mp_SigBit);
  891.     creatclisig = 1 << creatsignum;
  892.     unblanksig = 1 << blanksignum;
  893.     mousemovesig = 1 << mousemovenum;
  894.     inputRequestBlock->io_Command = IND_ADDHANDLER;
  895.     inputRequestBlock->io_Data = (APTR) & handlerStuff;
  896.     DoIO ((struct IORequest *) inputRequestBlock);
  897.     if (OpenDevice (TIMERNAME, UNIT_VBLANK, (struct IORequest *) timerreq, 0))
  898.       goto abort;
  899.     QueueTimer (timerreq, 1 /* 1/60th of a second */ );
  900.   }
  901.  
  902.   {
  903.     UWORD newsecond;
  904.     ULONG sig, Seconds, Micros, LastSeconds = 0;
  905.     int topscreenwidth = GfxBase->NormalDisplayColumns;
  906.     int topscreenheight = GfxBase->NormalDisplayRows;
  907.  
  908.     for (;;)
  909.       {
  910.     sig = Wait (creatclisig | unblanksig | timersig |
  911.             mousemovesig | SIGBREAKF_CTRL_C);
  912.  
  913.     if (sig & mousemovesig)
  914.       {
  915.         int left, right, upper, lower;
  916.  
  917.         if (!blankscreen)
  918.           {
  919.         int lock = LockIBase (0);
  920.         struct Screen *screen = IntuitionBase->FirstScreen;
  921.  
  922.         while (screen && IntuitionBase->MouseY <
  923.                (screen->TopEdge << ((screen->ViewPort.Modes & LACE) ? 0 : 1)))
  924.           screen = screen->NextScreen;
  925.         if (screen)
  926.           {
  927.             topscreenwidth = screen->Width << ((screen->ViewPort.Modes & HIRES) ? 0 : 1);
  928.             topscreenheight = screen->Height >> ((screen->ViewPort.Modes & LACE) ? 1 : 0);
  929.           }
  930.         else
  931.           {
  932.             topscreenwidth = GfxBase->NormalDisplayColumns;
  933.             topscreenheight = GfxBase->NormalDisplayRows;
  934.           }
  935.         UnlockIBase (lock);
  936.           }
  937.  
  938.         left = IntuitionBase->MouseX < 10;
  939.         right = (topscreenwidth - IntuitionBase->MouseX) < 10;
  940.         upper = IntuitionBase->MouseY < 10;
  941.         lower = (topscreenheight - IntuitionBase->MouseY / 2) < 10;
  942.  
  943.         instantblank = ((((ULC == 1) && upper) || ((LLC == 1) && lower)) && left) ||
  944.           ((((URC == 1) && upper) || ((LRC == 1) && lower)) && right);
  945.         defeatblank = ((((ULC == 2) && upper) || ((LLC == 2) && lower)) && left) ||
  946.           ((((URC == 2) && upper) || ((LRC == 2) && lower)) && right);
  947.       }
  948.  
  949.     CurrentTime (&Seconds, &Micros);
  950.     newsecond = (Seconds != LastSeconds);
  951.     LastSeconds = Seconds;
  952.  
  953.     if (newsecond && !NEWPOPLITE && !blankscreen)
  954.       {
  955.         SHORT x = 0;
  956.         ULONG DIdle, DDisp, Usage;
  957.         long t;
  958.         struct tm *p;
  959.         char *timestr;
  960.  
  961.         UpfrontLayer (0L, titlewindow->WLayer);
  962.  
  963.         DIdle = ExecBase->IdleCount - LIdle;
  964.         DDisp = ExecBase->DispCount - LDisp;
  965.         LIdle = ExecBase->IdleCount;
  966.         LDisp = ExecBase->DispCount;
  967.         if (!DDisp)
  968.           DDisp++;
  969.  
  970.         if (MEMORYMONWIDTH)
  971.           {
  972.         int pixels;
  973.  
  974.         SetAPen (titleRP, 3);
  975.         pixels = AvailMem (MEMF_CHIP) * MEMORYMONWIDTH / maxchip;
  976.         RectFill (titleRP, x, 0, x+pixels, ((WindowHeight/2) - 1));
  977.             SetAPen (titleRP, 1);
  978.         RectFill (titleRP, x+pixels+1, 0, MEMORYMONWIDTH, ((WindowHeight/2) - 1));
  979.  
  980.         SetAPen (titleRP, 2);
  981.         pixels = AvailMem (MEMF_FAST) * MEMORYMONWIDTH / maxfast;
  982.         RectFill (titleRP, x, (WindowHeight/2), x+pixels, (WindowHeight - 1));
  983.             SetAPen (titleRP, 1);
  984.         RectFill (titleRP, x+pixels+1, (WindowHeight/2), MEMORYMONWIDTH, (WindowHeight - 1));
  985.  
  986.             x = MEMORYMONWIDTH;
  987.           }
  988.  
  989.         x += GAPBETWEEN3;
  990.  
  991.         if (scsifriendinstalled)
  992.           {
  993.         Usage = (scsiDisp * 256) / (DDisp + DIdle);
  994.         if (Usage > MAXSCSIUSAGE)
  995.           Usage = MAXSCSIUSAGE;
  996.         SetAPen (titleRP, 3);
  997.         ScrollRaster (titleRP, 1, 0, x, 0, x + SCSIIOMONWIDTH, (WindowHeight - 1));
  998.         x += SCSIIOMONWIDTH;
  999.         Move (titleRP, x, (WindowHeight - 1));
  1000.         Draw (titleRP, x, WindowHeight - ((WindowHeight * Usage) / MAXSCSIUSAGE));
  1001.         scsiDisp = 0;
  1002.           }
  1003.         else
  1004.           x += SCSIIOMONWIDTH;
  1005.  
  1006.         x += GAPBETWEEN2;
  1007.  
  1008.         if (CPULOADMONWIDTH)
  1009.           {
  1010.             /* There be magic below!  Where does 456 come from? :-) */
  1011.             if (scsiDisp < DDisp)
  1012.               Usage = ((DDisp - scsiDisp) * 456) / (DDisp + DIdle);
  1013.             else
  1014.               Usage = 0;
  1015.             if (Usage < 200)
  1016.               Usage = 0;
  1017.             else
  1018.               Usage = Usage - 200;
  1019.             ScrollRaster (titleRP, 1, 0, x, 0, x + CPULOADMONWIDTH, (WindowHeight - 1));
  1020.             x += CPULOADMONWIDTH;
  1021.             SetAPen (titleRP, 2);
  1022.             Move (titleRP, x, (WindowHeight - 1));
  1023.             Draw (titleRP, x, WindowHeight - ((WindowHeight * Usage) / 256));
  1024.           }
  1025.  
  1026.         x += GAPBETWEEN;
  1027.  
  1028.         if (MAXTEXTWIDTH)
  1029.           {
  1030.             time (&t);
  1031.             p = localtime (&t);
  1032.             timestr = asctime (p);
  1033.         if (WIMPYCLOCK)
  1034.           switch ((timestr[11] - '0') * 10 + (timestr[12] - '0'))
  1035.             {
  1036.             case 0: timestr[11] = '1'; timestr[12] = '2'; goto am;
  1037.             case 12: goto pm;
  1038.             case 13: timestr[11] = '0'; timestr[12] = '1'; goto pm;
  1039.             case 14: timestr[11] = '0'; timestr[12] = '2'; goto pm;
  1040.             case 15: timestr[11] = '0'; timestr[12] = '3'; goto pm;
  1041.             case 16: timestr[11] = '0'; timestr[12] = '4'; goto pm;
  1042.             case 17: timestr[11] = '0'; timestr[12] = '5'; goto pm;
  1043.             case 18: timestr[11] = '0'; timestr[12] = '6'; goto pm;
  1044.             case 19: timestr[11] = '0'; timestr[12] = '7'; goto pm;
  1045.             case 20: timestr[11] = '0'; timestr[12] = '8'; goto pm;
  1046.             case 21: timestr[11] = '0'; timestr[12] = '9'; goto pm;
  1047.             case 22: timestr[11] = '1'; timestr[12] = '0'; goto pm;
  1048.             case 23: timestr[11] = '1'; timestr[12] = '1'; goto pm;
  1049.             default: am: timestr[19] = 'a'; break;
  1050.             pm: timestr[19] = 'p'; break;
  1051.             }
  1052.             Move (titleRP, x, STARTYOFFSET);
  1053.             Text (titleRP, timestr, 24);
  1054.  
  1055.             x += TextLength (titleRP, timestr, 24);
  1056.             SetAPen (titleRP, 1);
  1057.             if (x < (WindowWidth - 1))
  1058.               RectFill (titleRP, x, 0, (WindowWidth - 1), (WindowHeight - 1));
  1059.           }
  1060.       }
  1061.  
  1062.     if (blankscreen)
  1063.       {
  1064.         if (NICENEWPOP)
  1065.           {
  1066.         if (newsecond)
  1067.           {
  1068.             /*changecolor ();*/
  1069.             SetTaskPri (child, 10);
  1070.           }
  1071.           }
  1072.         else
  1073.           {
  1074.         /*if (newsecond)*/
  1075.           changecolor ();
  1076.         updatedisplay ();
  1077.           }
  1078.       }
  1079.  
  1080.     if (sig & SIGBREAKF_CTRL_C)
  1081.       goto abort;
  1082.  
  1083.     if (sig & creatclisig)
  1084.       {
  1085.         if (!(blankscreen && LOCK))
  1086.           {
  1087.         WBenchToFront ();
  1088.         if (DOSBase->dl_lib.lib_Version < 36)
  1089.           Execute(COMMAND, nullfh, nullfh);
  1090.         else
  1091.             {
  1092.             static struct TagItem stags[4] =
  1093.             {
  1094.               {SYS_Input, NULL},
  1095.               {SYS_Output, NULL},
  1096.               {SYS_UserShell, TRUE},
  1097.               {TAG_DONE, 0}
  1098.             };
  1099.  
  1100.             stags[0].ti_Data = nullfh;
  1101.             System(COMMAND, stags);
  1102.               }
  1103.         if (blankscreen)
  1104.           goto unblank;
  1105.           }
  1106.       }
  1107.  
  1108.     {
  1109.       static WORD joy0, oldjoy0, joy1, oldjoy1;
  1110.  
  1111.       joy0 = *((WORD *)0x00dff00a) & 0x0303;
  1112.       joy1 = *((WORD *)0x00dff00c) & 0x0303;
  1113.       if ((joy0 != oldjoy0) || (joy1 != oldjoy1))
  1114.         {
  1115.           oldjoy0 = joy0;
  1116.           oldjoy1 = joy1;
  1117.           if (blankscreen && !instantblank)
  1118.         goto unblank;
  1119.         }
  1120.     }
  1121.  
  1122.     if ((sig & unblanksig) && blankscreen && !instantblank)
  1123.       {
  1124.       unblank:
  1125.         if (LOCK && ReqBase)
  1126.           {
  1127.         char InputPassWord[MAXPASSWORD];
  1128.             static int trywait;
  1129.  
  1130.         SetRGB4 (blankVP, 17, 4, 4, 4);
  1131.         SetRGB4 (blankVP, 18, 8, 8, 8);
  1132.         SetRGB4 (blankVP, 19, 12, 12, 12);
  1133.         createsecurer ();
  1134.         InputPassWord[0] = 0;
  1135.         if ((trywait++ % 2) /*&&
  1136.             GetString (InputPassWord, "Type password, then hit return.",
  1137.             blankwindow, MAXPASSWORD + 10, MAXPASSWORD)*/)
  1138.           {
  1139.             killsecurer ();
  1140.             UpfrontLayer (0L, blankwindow->WLayer);
  1141.             if (strcmp (InputPassWord, PASSWORD))
  1142.               goto noway;
  1143.           }
  1144.         else
  1145.           {
  1146.             killsecurer ();
  1147.             UpfrontLayer (0L, blankwindow->WLayer);
  1148.             goto noway;
  1149.           }
  1150.           }
  1151.         if (NICENEWPOP)
  1152.           killchild ();
  1153.         CloseWindow (blankwindow);
  1154.         CloseScreen (blankscreen);
  1155.         blankscreen = NULL;
  1156.         noevents = 0;
  1157.       noway: ;
  1158.       }
  1159.  
  1160.     if (sig & timersig)
  1161.       {
  1162.         GetMsg (timerport);
  1163.         if (blankscreen && NICENEWPOP)
  1164.           QueueTimer (timerreq, 60 /* One second */ );
  1165.         else
  1166.           QueueTimer (timerreq, 1 /* 1/60th of a second*/ );
  1167.  
  1168.         if ((instantblank || (noevents++ >= (TIMEOUT * 60))) && !blankscreen && !defeatblank && TIMEOUT)
  1169.           {
  1170.         NewScreen.Height = GfxBase->NormalDisplayRows * 2;
  1171.         NewScreen.Width = GfxBase->NormalDisplayColumns;
  1172.  
  1173.         if (blankscreen = OpenScreen (&NewScreen))
  1174.           {
  1175.             ylim = blankscreen->Height - 1;
  1176.             xlim = blankscreen->Width - 1;
  1177.             NewBlankerWindow.Screen = blankscreen;
  1178.             NewBlankerWindow.Height = blankscreen->Height;
  1179.             NewBlankerWindow.Width = blankscreen->Width;
  1180.             if (blankwindow = OpenWindow (&NewBlankerWindow))
  1181.               {
  1182.             static UWORD __chip NULLpointer[1] = {0x0000};
  1183.  
  1184.             blankRP = blankwindow->RPort;
  1185.             blankVP = &(blankscreen->ViewPort);
  1186.             SetPointer (blankwindow, NULLpointer, 0, 0, 0, 0);
  1187.             changecolor ();
  1188.             SetRGB4 (blankVP, 0, 0, 0, 0);
  1189.             SetRGB4 (blankVP, 17, 0, 0, 0);
  1190.             SetRGB4 (blankVP, 18, 0, 0, 0);
  1191.             SetRGB4 (blankVP, 19, 0, 0, 0);
  1192.             SetDrMd (blankRP, JAM1);
  1193.             UpfrontLayer (0L, blankwindow->WLayer);
  1194.             if (NICENEWPOP)
  1195.               createchild ();
  1196.               }
  1197.             else
  1198.               {
  1199.                 CloseScreen (blankscreen);
  1200.                 blankscreen = NULL;
  1201.               }
  1202.           }
  1203.           }
  1204.       }
  1205.  
  1206.     if (blankscreen)
  1207.       ScreenToFront (blankscreen);
  1208.       }
  1209.   }
  1210.  
  1211. abort:
  1212. #define SafeClose(fh) if (fh) Close (fh)
  1213. #define SafeDeletePort(port) if (port) DeletePort (port)
  1214. #define SafeCloseLibrary(lib) if (lib) CloseLibrary ((struct Library *) lib)
  1215. #define SafeFreeSignal(signum) if (signum != -1) FreeSignal (signum)
  1216. #define SafeCloseFont(font) if (font) CloseFont (font)
  1217. #define SafeCloseWindow(window) if (window) CloseWindow (window)
  1218.   SetTaskPri (buddy, oldPriority);
  1219.   SafeDeletePort (port);
  1220.   if (scsifriendinstalled)
  1221.     {
  1222.       Forbid ();
  1223.       if (scsifriend = FindTask (SCSITASKNAME))
  1224.     if (scsifriend->tc_Switch == scsifriendlosing)
  1225.       {
  1226.         UBYTE oldpri = SetTaskPri (scsifriend, 21);
  1227.         Permit ();
  1228.         /* Make SURE scsifriend has lost the CPU!
  1229.         // I don't know why this fixed a problem
  1230.         // people were having with A3000's/2.0/C=
  1231.         // controllers, but it seems to work! */
  1232.         Forbid ();
  1233.         SetTaskPri (scsifriend, oldpri);
  1234.         scsifriend->tc_Flags &= ~TF_SWITCH;
  1235.         scsifriend->tc_Switch = NULL;
  1236.       }
  1237.       Permit ();
  1238.     }
  1239.   SafeCloseWindow (titlewindow);
  1240.   if (timerreq)
  1241.     {
  1242.       if (timerreq->tr_node.io_Device)
  1243.         {
  1244.           if (!CheckIO ((struct IOStdReq *) timerreq));
  1245.         {
  1246.           AbortIO ((struct IOStdReq *) timerreq);
  1247.           WaitIO ((struct IOStdReq *) timerreq);
  1248.         }
  1249.       CloseDevice ((struct IORequest *) timerreq);
  1250.     }
  1251.       DeleteExtIO ((struct IOStdReq *) timerreq);
  1252.     }
  1253.   if (inputRequestBlock)
  1254.     {
  1255.       if (inputRequestBlock->io_Device)
  1256.     {
  1257.       inputRequestBlock->io_Command = IND_REMHANDLER;
  1258.       inputRequestBlock->io_Data = (APTR) & handlerStuff;
  1259.       DoIO ((struct IORequest *) inputRequestBlock);
  1260.       CloseDevice ((struct IORequest *) inputRequestBlock);
  1261.     }
  1262.       DeleteExtIO (inputRequestBlock);
  1263.     }
  1264.   SafeCloseFont (textFont);
  1265.   SafeDeletePort (timerport);
  1266.   SafeFreeSignal (creatsignum);
  1267.   SafeFreeSignal (blanksignum);
  1268.   SafeFreeSignal (mousemovenum);
  1269.   if (blankscreen)
  1270.     {
  1271.       if (NICENEWPOP)
  1272.     killchild ();
  1273.       CloseWindow (blankwindow);
  1274.       CloseScreen (blankscreen);
  1275.     }
  1276.   SafeCloseLibrary (IntuitionBase);
  1277.   SafeCloseLibrary (GfxBase);
  1278.   SafeCloseLibrary (LayersBase);
  1279.   SafeCloseLibrary (DiskfontBase);
  1280.   SafeCloseLibrary (ExecBase);
  1281.   SafeCloseLibrary (ReqBase);
  1282.   SafeDeletePort (inputDevPort);
  1283.   SafeClose (nullfh);
  1284.  
  1285.   grandexit: ;
  1286.   return (0);
  1287. }
  1288.  
  1289. void 
  1290. changecolor (void)
  1291. {
  1292.   static struct color currentcolor = {127, 0, 254};
  1293.   static struct color colordelta = {-1, 1, 1};
  1294.   static unsigned long table[] = { (1<<16) + 1, 0, 0, 0, 0 };
  1295.  
  1296.   switch (rand () % 3)
  1297.     {
  1298.     case 0:
  1299.       currentcolor.red += colordelta.red;
  1300.       if (currentcolor.red == 0 ||
  1301.       currentcolor.red == 255)
  1302.     colordelta.red = -colordelta.red;
  1303.       break;
  1304.     case 1:
  1305.       currentcolor.green += colordelta.green;
  1306.       if (currentcolor.green == 0 ||
  1307.       currentcolor.green == 255)
  1308.     colordelta.green = -colordelta.green;
  1309.       break;
  1310.     case 2:
  1311.       currentcolor.blue += colordelta.blue;
  1312.       if (currentcolor.blue == 0 ||
  1313.       currentcolor.blue == 255)
  1314.     colordelta.blue = -colordelta.blue;
  1315.       break;
  1316.     }
  1317.  
  1318.   table[1] = ((unsigned long) currentcolor.red) << 24;
  1319.   table[2] = ((unsigned long) currentcolor.green) << 24;
  1320.   table[3] = ((unsigned long) currentcolor.blue) << 24;
  1321.   LoadRGB32 (blankVP, table);
  1322. }
  1323.  
  1324. void 
  1325. updatedisplay (void)
  1326. {
  1327.   static SHORT x[2], y[2], xd[2], yd[2], ox[2][16], oy[2][16];
  1328.   static j;
  1329.   SHORT i, k;
  1330.  
  1331.   if (j == 0)
  1332.     {
  1333.       x[0] = rand () % xlim + 1;
  1334.       if ((x[1] = x[0] + rand () % (xlim / 6) - (xlim / 12)) > xlim)
  1335.     x[1] = xlim;
  1336.       if (x[1] < 0)
  1337.     x[1] = 0;
  1338.       y[0] = rand () % ylim + 1;
  1339.       if ((y[1] = y[0] + rand () % (ylim / 4) - (ylim / 8)) > ylim)
  1340.     y[1] = ylim;
  1341.       if (y[1] < 0)
  1342.     y[1] = 0;
  1343.       xd[0] = 11;
  1344.       yd[0] = 7;
  1345.       xd[1] = 3;
  1346.       yd[1] = 4;
  1347.     }
  1348.   SetAPen (blankRP, 0);
  1349.   Move (blankRP, ox[0][j & 15], oy[0][j & 15]);
  1350.   Draw (blankRP, ox[1][j & 15], oy[1][j & 15]);
  1351.   SetAPen (blankRP, 1);
  1352.   Move (blankRP, x[0], y[0]);
  1353.   Draw (blankRP, x[1], y[1]);
  1354.   for (i = 0; i < 2; i++)
  1355.     {
  1356.       ox[i][j & 15] = x[i];
  1357.       oy[i][j & 15] = y[i];
  1358.       x[i] += xd[i];
  1359.       y[i] += yd[i];
  1360.       if (abs (x[1] - x[0]) > xlim / 4)
  1361.     {
  1362.       x[i] -= xd[i] * 4 / 3;
  1363.       xd[i] = -xd[i] / 2;
  1364.     }
  1365.       if (abs (y[1] - y[0]) > ylim / 3)
  1366.     {
  1367.       y[i] -= yd[i] * 4 / 3;
  1368.       yd[i] = -yd[i] / 2;
  1369.     }
  1370.       if (x[i] < 0)
  1371.     {
  1372.       x[i] = 0;
  1373.       xd[i] = -xd[i];
  1374.     }
  1375.       else if (x[i] > xlim)
  1376.     {
  1377.       x[i] = xlim;
  1378.       xd[i] = -xd[i];
  1379.     }
  1380.       if (y[i] < 0)
  1381.     {
  1382.       y[i] = 0;
  1383.       yd[i] = -yd[i];
  1384.     }
  1385.       else if (y[i] > ylim)
  1386.     {
  1387.       y[i] = ylim;
  1388.       yd[i] = -yd[i];
  1389.     }
  1390.       if (((rand () >> 5) & 127) < 2)
  1391.     {
  1392.       if (xd[i] < 1)
  1393.         k = 1;
  1394.       xd[i] = (rand () >> 5) & 7;
  1395.       if (k == (1 - i))
  1396.         xd[i] = -xd[i];
  1397.       k = 0;
  1398.     }
  1399.       if (((rand () >> 5) & 255) < 50)
  1400.     {
  1401.       if (yd[i] < 1)
  1402.         k = 1;
  1403.       yd[i] = (rand () >> 5) & 7;
  1404.       if (k == (1 - i))
  1405.         yd[i] = -yd[i];
  1406.       k = 0;
  1407.     }
  1408.     }
  1409.   ++j;
  1410. }
  1411.  
  1412. void 
  1413. QueueTimer (struct timerequest * tr, ULONG ticks)
  1414. {
  1415.   tr->tr_node.io_Command = TR_ADDREQUEST;
  1416.   tr->tr_time.tv_secs = ticks / 60;
  1417.   tr->tr_time.tv_micro = (ticks % 60) * 1000000 / 60;
  1418.   SendIO ((struct IORequest *) tr);
  1419. }
  1420.